﻿using log4net;
using MaterialDesignThemes.Wpf;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;
using UIWindows.Enums;
using UIWindows.ViewModels.Dialogs;
using UIWindows.Views.Dialogs;
using XingLucifer.IBase.Enums;

namespace UIWindows.Tools.Helper
{
    public static class DialogLogHelper
    {
        private static Brush _error = null;
        private static Brush _warn;
        private static Brush _info;
        private static readonly object _obj;
        private static GlobalStatics.LogStatic _homeStatic;
     
        public static void Init()
        {
            if (_error == null)
            {
                _error = new SolidColorBrush(Color.FromArgb(0xFF, 0xF3, 0x51, 0x51));
                _warn = new SolidColorBrush(Color.FromArgb(0xFF, 0xF3, 0xCE, 0x51));
                _info = new SolidColorBrush(Color.FromArgb(0xF9, 0x08, 0xB9, 0x89));
                _homeStatic = Domains.ObjectContainer.ResolveSingleton<GlobalStatics.LogStatic>();
            }
        }

        private static Func<string, MessageLevelType, bool, PopUpTypes, Visibility, Task<object>> _messageDialogs = null;
        private static ILog _run = LogManager.GetLogger("message");
        private static ILog _operation = LogManager.GetLogger("operation");
        /// <summary>
        /// 消息弹窗
        /// </summary>
        /// <param name="str">消息</param>
        /// <param name="levelType">消息等级枚举</param>
        /// <param name="isOperation">是否操作调用该方法</param>
        /// <param name="visibility">是否显示确认键</param>
        public static Task<object> MessageDialogs(this string str, MessageLevelType levelType, bool isOperation = false, PopUpTypes hostDialog = PopUpTypes.UserWindow, Visibility visibility = Visibility.Collapsed)
        {
            if (_messageDialogs == null)
            {
                _messageDialogs = new Func<string, MessageLevelType, bool, PopUpTypes, Visibility, Task<object>>(async (str, levelType, isOper, host, visy) =>
                {
                    if (DialogHost.IsDialogOpen(host.ToString())) DialogHost.Close(host.ToString());
                    string title = levelType.ToString();
                    Brush brush = null;
                    PackIconKind pack = PackIconKind.AllInclusive;
                    title = $"{title[0]}  {title[1]}";
                    switch (levelType)
                    {
                        case MessageLevelType.错误:
                            brush = _error;
                            pack = PackIconKind.AlertCircleOutline;
                            if (isOperation) { _operation.Error(str.Replace("\r\n", "<=>")); OperationLogAdd(str, _error, levelType); } else { _run.Error(str.Replace("\r\n", "<=>")); }
                            break;
                        case MessageLevelType.信息:
                            brush = _info;
                            pack = PackIconKind.BookInformationVariant;
                            if (isOperation) { _operation.Info(str.Replace("\r\n", "<=>")); OperationLogAdd(str, _info, levelType); } else { _run.Info(str.Replace("\r\n", "<=>")); }
                            break;
                        case MessageLevelType.警告:
                            brush = _warn;
                            pack = PackIconKind.AlertOutline;
                            if (isOperation) { _operation.Warn(str.Replace("\r\n", "<=>")); OperationLogAdd(str, _warn, levelType); } else { _run.Warn(str.Replace("\r\n", "<=>")); }
                            break;
                        case MessageLevelType.成功:
                            brush = _info;
                            pack = PackIconKind.ChatBubble;
                            if (isOperation) { _operation.Info(str.Replace("\r\n", "<=>")); OperationLogAdd(str, _info, levelType); } else { _run.Info(str.Replace("\r\n", "<=>")); }
                            break;
                    }
                    return await DialogHost.Show(new MessageDialogs()
                    {
                        DataContext = new MessageDialogsViewModel(title, str, pack, brush, visy)
                    }, host.ToString());
                });
            }
            return ThreadHelper.IsUIThread(() => _messageDialogs(str, levelType, isOperation, hostDialog, visibility), () => ThreadHelper.CrossThreadAsync(sender => _messageDialogs(str, levelType, isOperation, hostDialog, visibility), _obj));
        }

        /// <summary>
        /// 运行日志
        /// </summary>
        /// <param name="str"></param>
        /// <param name="levelType"></param>
        public static void RunLog(this string str, MessageLevelType levelType)
        {
            try
            {
                switch (levelType)
                {
                    case MessageLevelType.错误:
                        _run.Error(str);
                        LogAdd(str, _error, levelType);
                        break;
                    case MessageLevelType.信息:
                        _run.Info(str);
                        LogAdd(str, Brushes.Black, levelType);
                        break;
                    case MessageLevelType.警告:
                        _run.Warn(str);
                        LogAdd(str, _warn, levelType);
                        break;
                    case MessageLevelType.成功:
                        _run.Debug(str);
                        LogAdd(str, _info, levelType);
                        break;
                }
                if (_homeStatic.LogList.Count > 800)
                {
                    _homeStatic.LogList.RemoveAt(799);

                }
            }
            catch (Exception ex)
            {
                _run.Error($"RunLog 添加日志信息时发生异常：{ex}");
            }
        }
        private static void LogAdd(string str, Brush brush, MessageLevelType levelType)
        {
            try
            {
                _homeStatic.LogList.Insert(0, new Models.RunMessageModel()
                {
                    Level = levelType,
                    Message = str,
                    Color = brush,
                    Time = DateTime.Now.ToString("HH:mm:ss:fff"),
                });
            }
            catch (Exception ex)
            {
                _run.Error($"LogAdd 添加日志时发生异常：{ex}");
            }
        }
        static object mesLogLocker = new object();
        static string header = "调用状态,请求接口,条码,URL,开始时间,结束时间,耗时(ms),请求参数,返回参数,设备编码,生产类型\r\n";
        /// <summary>
        /// MES接口调用记录
        /// </summary>
        /// <param name="barcode">条码</param>
        /// <param name="interfaceName">接口名称</param>
        /// <param name="result_message">接口返回信息</param>
        /// <param name="str_post">请求参数</param>
        /// <param name="str_result">调用结果</param>
        /// <param name="time">调用耗时</param>
        /// <param name="dateTime">调用时间</param>
        /// <param name="devicetype">设备编号</param>
        /// <param name="type">生产类型</param>
        /// <param name="logtype">日志类型</param>
        public static void MesLog(this string barcode, string interfaceName, string result_message, string str_post, string str_result,
            long time, DateTime dateTime, string devicetype, string type, string logtype,string url)
        {
           
            try
            {
                var msgLog = _homeStatic.LNModels.FirstOrDefault(x => x.LoggerName == logtype);
                if (msgLog != null )
                {
                    string logPath = $"{msgLog.SavePath}{DateTime.Now.ToString("yyyy-MM-dd")}.csv";
                    if (!File.Exists(logPath))
                    {
                        string basePath = Path.GetDirectoryName(logPath);
                        Directory.CreateDirectory(basePath);
                        lock (mesLogLocker)
                        {
                            if (!File.Exists(logPath) && !string.IsNullOrEmpty(header))
                            {
                                File.WriteAllText(logPath, header, Encoding.UTF8);
                            }
                        }
                    }
                }
                var _mes = LogManager.GetLogger(logtype);
                _homeStatic.MesLog.Insert(0, new Models.MesLogModel()
                {
                    RunTime = dateTime,
                    ResultMessage = result_message,
                    BarCode = barcode,
                    InterfaceName = interfaceName,
                    TimeConsuming = time,
                });
                // 调用状态,请求接口,条码,URL,开始时间,结束时间,耗时(ms),请求参数,返回信息,设备编码,生产类型 
                var _meg = $"{str_result},{interfaceName},{barcode},{url},{dateTime:yyyy/MM/dd HH:mm:ss.fff},{DateTime.Now:yyyy/MM/dd HH:mm:ss.fff},{time},\"{str_post.Replace("\"", "\"\"")}\",\"{result_message.Replace("\"", "\"\"")}\",{devicetype},{type}";
                _mes.Info(_meg);
                if (_homeStatic.MesLog.Count > 400)
                {
                    _homeStatic.MesLog.RemoveAt(399);
                }
            }
            catch (Exception ex)
            {
                _run.Error($"MesLog 添加日志信息时发生异常：{ex}");
            }
        }
       
        public static void OperationLog(this string message, MessageLevelType levelType)
        {
            try
            {
                switch (levelType)
                {
                    case MessageLevelType.错误:
                        _operation.Error(message.Replace("\r\n", "<=>"));
                        OperationLogAdd(message, _error, levelType);
                        break;
                    case MessageLevelType.警告:
                        _operation.Warn(message.Replace("\r\n", "<=>"));
                        OperationLogAdd(message, _warn, levelType);
                        break;
                    case MessageLevelType.信息:
                        _operation.Info(message.Replace("\r\n", "<=>"));
                        OperationLogAdd(message, _info, levelType);
                        break;
                    case MessageLevelType.成功:
                        _operation.Debug(message.Replace("\r\n", "<=>"));
                        OperationLogAdd(message, _info, levelType);
                        break;
                }
            }
            catch (Exception ex)
            {
                _run.Error($"OperationLog 添加操作信息时发生异常：{ex}");
            }
        }

        private static void OperationLogAdd(string message, Brush brush, MessageLevelType levelType)
        {
            try
            {
                _homeStatic.OperationLog.Insert(0, new Models.RunMessageModel
                {
                    Message = message,
                    Color = brush,
                    Level = levelType,
                    Time = DateTime.Now.ToString("T")
                });
                if (_homeStatic.OperationLog.Count > 500)
                {
                    _homeStatic.OperationLog.RemoveAt(499);
                }
            }
            catch (Exception ex)
            {
                _run.Error($"OperationLogAdd 添加操作记录显示时发生异常：{ex}");
            }
        }

        /// <summary>
        /// MES专用弹窗
        /// </summary>
        /// <param name="str"></param>
        public static void MESDialog(this string interfaceName, string messageEncoding, string messageContent)
        {
            ThreadHelper.CrossThreadAsync(sender =>
            {
                System.Threading.Thread.Sleep(100);
                if (DialogHost.IsDialogOpen(PopUpTypes.UserWindow.ToString())) DialogHost.Close(PopUpTypes.UserWindow.ToString());
                DialogHost.Show(new MESMessageShow()
                {
                    DataContext = new MESMessageShowViewModel(interfaceName, messageEncoding, messageContent),
                }, PopUpTypes.UserWindow.ToString()).ConfigureAwait(false);
                return null;
            }, _obj);
        }
    }
}
